package cn.wolfcode.luowowo.service.impl;

import cn.wolfcode.luowowo.domain.Destination;
import cn.wolfcode.luowowo.domain.Strategy;
import cn.wolfcode.luowowo.domain.StrategyCatalog;
import cn.wolfcode.luowowo.domain.StrategyTheme;
import cn.wolfcode.luowowo.query.StrategyQuery;
import cn.wolfcode.luowowo.repository.StrategyRepository;
import cn.wolfcode.luowowo.service.IDestinationService;
import cn.wolfcode.luowowo.service.IStrategyCatalogService;
import cn.wolfcode.luowowo.service.IStrategyService;
import cn.wolfcode.luowowo.service.IStrategyThemeService;
import cn.wolfcode.luowowo.util.DBHelper;
import cn.wolfcode.luowowo.vo.CatalogVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;

//攻略明细业务实现类
@Service
public class StrategyServiceImpl implements IStrategyService {
    //注入攻略明细数据接口
    @Autowired
    private StrategyRepository strategyRepository;

    @Autowired
    private MongoTemplate mongoTemplate;
    //攻略分类服务
    @Autowired
    private IStrategyCatalogService strategyCatalogService;
    //攻略主题服务
    @Autowired
    private IStrategyThemeService strategyThemeService;
    //目的地服务
    @Autowired
    private IDestinationService destinationService;

    //根据攻略明细id查询攻略明细信息
    @Override
    public Strategy get(String id) {
        return strategyRepository.findById(id).orElse(null);
    }

    @Override
    public void save(Strategy strategy) {
        //防止调用者传了id覆盖了数据
        strategy.setId(null);
        //处理一些冗余字段
        //目的地的id和name
        StrategyCatalog catalog = strategyCatalogService.get(strategy.getCatalogId());
        strategy.setDestId(catalog.getDestId());
        strategy.setDestName(catalog.getDestName());
        //是否国内
        List<Destination> destinations = destinationService.getToasts(catalog.getDestId());
        strategy.setIsabroad("中国".equals(destinations.get(0).getName())?Strategy.ABROAD_YES:Strategy.ABROAD_NO);
        //分类name
        strategy.setCatalogName(catalog.getName());
        //主题name
        strategy.setThemeName(strategyThemeService.get(strategy.getThemeId()).getName());
        //创建时间
        strategy.setCreateTime(new Date());
        strategyRepository.save(strategy);
    }

    @Override
    public void update(Strategy strategy) {
        //局部更新之多个
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(strategy.getId()));
        //方式一   一个一个设置要更新的字段
        //Update update = new Update().set("title:",title);
        //方式2   抽取一个通用方法
        DBHelper.update(strategy , mongoTemplate , query , "title" , "subTitle" ,
                "coverUrl" , "state" ,
                "summary" , "content");
    }

    @Override
    public void delete(String id) {
        strategyRepository.deleteById(id);
    }

    //分页查询
    @Override
    public Page<Strategy> list(StrategyQuery qo) {
        //创建条件对象
        Query query = new Query();
        //处理查询的条件
        if (StringUtils.hasLength(qo.getDestId())){
            query.addCriteria(Criteria.where("destId").is(qo.getDestId()));
        }
        if (StringUtils.hasLength(qo.getThemeId())){
            query.addCriteria(Criteria.where("themeId").is(qo.getThemeId()));
        }
        //调用数据库工具类查询
        return DBHelper.PagingQuery(mongoTemplate, query, Strategy.class,qo.getPageable());
    }
    //聚合查询,按目的地分组的攻略分类
    @Override
    public List<CatalogVO> groupList() {
        List<CatalogVO> list = new ArrayList<>();
        TypedAggregation<StrategyCatalog> agg = Aggregation.newAggregation(StrategyCatalog.class,
                Aggregation.group("destName").
                        push("name").as("names").
                        push("id").as("ids")
        );
        AggregationResults<Map> result = mongoTemplate.aggregate(agg,Map.class);
        List<Map> datas = result.getMappedResults();
        for (Map data : datas) {
            CatalogVO vo = new CatalogVO();
            vo.setDestName(data.get("_id").toString());
            List<Map<String, Object>> mm = new ArrayList<>();
            List<Object> names = (List<Object>) data.get("names");
            List<Object> ids = (List<Object>) data.get("ids");
            for (int i = 0;i < names.size(); i++) {
                Map<String, Object> vv = new HashMap<>();
                String name = names.get(i).toString();
                String id = ids.get(i).toString();
                vv.put("id", id);
                vv.put("name", name);
                mm.add(vv);
            }
            vo.setMapList(mm);
            list.add(vo);
        }
        return list;
    }

    //下架
    @Override
    public void changeState(String id, String state) {
        //局部更新之单个
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(id));
        Update update = new Update().set("state",state);
        mongoTemplate.updateFirst(query , update , Strategy.class);
    }
    //分类下的所有攻略
    @Override
    public List<Strategy> findByCatalogId(String id) {
        return  strategyRepository.findByCatalogId(id);
    }
    //目的地下点击量前三的攻略
    @Override
    public List<Strategy> viewnumTop3(String destId) {
        /*//按点击量倒序查询
        List<Strategy> list = strategyRepository.findByDestIdOrderByViewnumDesc(destId);
        //截取前三个
        return list.subList(0, 3);*/
        //按点击量倒序查询前三个
        PageRequest pageable = PageRequest.of(0,3);
        List<Strategy> list = strategyRepository.findByDestIdOrderByViewnumDesc(destId , pageable);
        return list;
    }
    //获取所有攻略信息
    @Override
    public List<Strategy> allList() {
        return strategyRepository.findAll();
    }
}
